package com.jxtc.enterprise.tenant.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jxtc.enterprise.common.aspectj.TokenRequired;
import com.jxtc.enterprise.common.entity.DeliveryRiderBriefInfo;
import com.jxtc.enterprise.common.entity.Store;
import com.jxtc.enterprise.common.entity.Tenant;
import com.jxtc.enterprise.common.mapper.StoreMapper;
import com.jxtc.enterprise.common.mapper.TenantMapper;
import com.jxtc.enterprise.common.utils.Result;
import com.jxtc.enterprise.common.utils.ResultCode;
import com.jxtc.enterprise.common.utils.ResultGenerator;
import com.jxtc.enterprise.common.vo.PaginationResponseVO;
import com.jxtc.enterprise.common.entity.DeliveryRider;
import com.jxtc.enterprise.common.mapper.RiderMapper;
import com.jxtc.enterprise.tenant.service.TenantRiderManageService;
import com.jxtc.enterprise.tenant.vo.riderManage.RiderInfoVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.text.MessageFormat;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/jxtc/enterprise/tenant/deliveryRiderManage")
@RequiredArgsConstructor
@Slf4j
@TokenRequired(role = TokenRequired.ROLE_TENANT)
public class TenantRiderManageController {

    @Autowired
    private RiderMapper riderMapper;

    @Autowired
    private StoreMapper storeMapper;

    @Autowired
    private TenantMapper tenantMapper;

    @Autowired
    private TenantRiderManageService tenantRiderManageService;

    /**
     * 接口 2.7.1 注册新骑手
     * @param riderInfoVo
     * @return
     */
    @PostMapping("/addNewDeliveryRider")
    public Result<Void> addNewDeliveryRider(@Valid @RequestBody RiderInfoVo riderInfoVo, HttpServletRequest request) {
        String requestId = UUID.randomUUID().toString();
        log.info("/addNewDeliveryRider, requestId {}, request body: {}", requestId, riderInfoVo);

        if (riderInfoVo.getVerifyFlag() == null) {
            throw new IllegalArgumentException("verifyFlag 不能为空");
        }

        // 由于骑手和商户端使用同一个小程序，避免注册新骑手时，骑手的手机号和商户手机号相同，导致使用手机号登录时，导致骑手登录到 商户页面
        List<Store> merchantsOfSamePhone = storeMapper.selectList(new LambdaQueryWrapper<Store>().eq(Store::getMerchantPhone, riderInfoVo.getPhone()).eq(Store::getDelFlag, false));
        if (!CollectionUtils.isEmpty(merchantsOfSamePhone)) {
            List<String> merchantNames = merchantsOfSamePhone.stream().map(Store::getMerchantName).collect(Collectors.toList());
            String errMsg = MessageFormat.format("商户: {0}, 已使用此手机号: {1}，请使用其他手机号注册新骑手", merchantNames, riderInfoVo.getPhone());
            log.error("requestId {}, {}", requestId, errMsg);
            return ResultGenerator.genFailResult(ResultCode.INTERNAL_SERVER_ERROR, errMsg);
        }
        // store表中商户使用的手机号没有注册时，在访问 delivery_rider_t 表，判断是否已经有其他骑手使用该手机号注册了
        List<DeliveryRider> deliveryRiders = riderMapper.selectList(
                new LambdaQueryWrapper<DeliveryRider>()
                        .eq(DeliveryRider::getPhone, riderInfoVo.getPhone())
                        .eq(DeliveryRider::getDelFlag, false));

        if (!CollectionUtils.isEmpty(deliveryRiders)) {
            log.error("requestId {}, 已有重复的骑手信息，{}",requestId, JSONObject.toJSONString(deliveryRiders));
            return ResultGenerator.genFailResult(ResultCode.INTERNAL_SERVER_ERROR, "手机号已存在，不能使用重复的手机号");
        }

        String tenantId = (String) request.getAttribute("userId");
        DeliveryRider deliveryRider = new DeliveryRider();
        deliveryRider.setName(riderInfoVo.getName());
        deliveryRider.setPhone(riderInfoVo.getPhone());
        deliveryRider.setPassword(riderInfoVo.getPassword());
        deliveryRider.setStatus(riderInfoVo.getStatus());
        deliveryRider.setType(riderInfoVo.getType());
        deliveryRider.setTenantId(tenantId);
        deliveryRider.setCreateTime(LocalDateTime.now());
        deliveryRider.setUpdateTime(LocalDateTime.now());

        tenantRiderManageService.addNewDeliveryRider(deliveryRider, tenantId, riderInfoVo.getVerifyFlag());

        return ResultGenerator.genSuccessResult();
    }

    /**
     * 接口 2.7.2 根据骑手姓名或手机号，查询匹配的骑手
     * @param queryParams
     * @return
     */
    @PostMapping("/queryDeliveryRiderByKeyword")
    public Result<PaginationResponseVO<JSONObject>> queryDeliveryRiderByKeyword(@RequestBody JSONObject queryParams, HttpServletRequest request) {
        String requestId = UUID.randomUUID().toString();
        log.info("requestId {}, /queryDeliveryRiderByKeyword, request body: {}", requestId, queryParams);
        String tenantId = (String) request.getAttribute("userId");
        String keyword = queryParams.getString("keyword");
        int pageNo = queryParams.getIntValue("pageNo");
        int pageSize = queryParams.getIntValue("pageSize");
        // select * from delivery_rider_t where del_flag = false and (name like '%xx%' or phone like '%xx%') and ( tenant_id = 'xxx' or type = 2) ;
        LambdaQueryWrapper<DeliveryRider> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DeliveryRider::getDelFlag, false);
        if (!ObjectUtils.isEmpty(keyword)) {
            queryWrapper.and(wrapper -> wrapper.like(DeliveryRider::getName, keyword).or().like(DeliveryRider::getPhone, keyword));
        }
        // 查询出隶属当前租户的骑手，或者 类型为 共享骑手 的骑手
        queryWrapper.and(wrapper -> wrapper.eq(DeliveryRider::getTenantId, tenantId).or().eq(DeliveryRider::getType, 2));

        // 查询结果，按照配送员记录在表中的创建时间降序排列
        queryWrapper.orderBy(true, false, DeliveryRider::getCreateTime);
        Page<DeliveryRider> page = new Page<>(pageNo, pageSize);
        Page<DeliveryRider> deliveryRiderDTOPage = riderMapper.selectPage(page, queryWrapper);

        // 页面上展示骑手隶属租户姓名，因此此处根据骑手隶属租户id，获取到租户姓名
        List<String> tenantIds = deliveryRiderDTOPage.getRecords().stream().map(DeliveryRider::getTenantId).collect(Collectors.toList());
        Map<String, String> tenantIdToNameMap;
        // 构建一个map，key为租户id，value为租户姓名，后续代码中会使用到该map
        if (!CollectionUtils.isEmpty(tenantIds)) {
            List<Tenant> tenantsBriefInfo = tenantMapper.selectList(new LambdaQueryWrapper<Tenant>().select(Tenant::getId, Tenant::getNickname).in(Tenant::getId, tenantIds));
            tenantIdToNameMap = tenantsBriefInfo.stream().collect(Collectors.toMap(Tenant::getId, Tenant::getNickname));
        } else {
            tenantIdToNameMap = new HashMap<>();
        }

        List<JSONObject> formattedRiderInfo = deliveryRiderDTOPage.getRecords().stream().map(rider -> {
            JSONObject riderInfoVo = new JSONObject();
            riderInfoVo.put("riderId", rider.getId());
            riderInfoVo.put("name", rider.getName());
            riderInfoVo.put("phone", rider.getPhone());
            riderInfoVo.put("password", rider.getPassword());
            String statusNameCn = tenantRiderManageService.convertRiderStatusCodeToNameCn(rider.getStatus());
            riderInfoVo.put("status", statusNameCn);
            String typeNameCn = tenantRiderManageService.convertRiderTypeCodeToNameCn(rider.getStatus());
            riderInfoVo.put("type", typeNameCn);
            riderInfoVo.put("tenantId", rider.getTenantId());
            String tenantName = tenantIdToNameMap.getOrDefault(rider.getTenantId(), rider.getTenantId());
            riderInfoVo.put("tenantName", tenantName);
            return riderInfoVo;
        }).collect(Collectors.toList());

        PaginationResponseVO<JSONObject> pagedRiderInfoVo =
                new PaginationResponseVO<>(deliveryRiderDTOPage.getTotal(), deliveryRiderDTOPage.getCurrent(), formattedRiderInfo);
        log.info("requestId {}, /queryDeliveryRiderByKeyword, response success", requestId);
        return ResultGenerator.genSuccessResult(pagedRiderInfoVo);
    }

    /**
     * 接口 2.7.3 编辑骑手信息
     * @param riderInfoVo
     * @return
     */
    @PostMapping("/editDeliveryRiderInfo")
    public Result<Void> editDeliveryRiderInfo(@RequestBody JSONObject riderInfoVo) {
        String requestId = UUID.randomUUID().toString();
        log.info("requestId {}, /editDeliveryRiderInfo, request body: {}", requestId, riderInfoVo);

        String riderId = riderInfoVo.getString("riderId");
        String name = riderInfoVo.getString("name");
        String phone = riderInfoVo.getString("phone");
        String password = riderInfoVo.getString("password");
        int status = riderInfoVo.getInteger("status");
        int type = riderInfoVo.getInteger("type");

        DeliveryRider deliveryRider = riderMapper.selectById(riderId);
        if (deliveryRider == null) {
            return ResultGenerator.genFailResult(ResultCode.FAIL, "骑手id: " + riderId + "不存在对应的骑手，请检查入参是否正确");
        }

        // 入参中的手机号 和 表中手机号不一样，表示 修改了 骑手手机号，需要进行处理
        if (!deliveryRider.getPhone().equalsIgnoreCase(phone)) {
            // 若编辑骑手信息时，编辑的是手机号，需要判断新设置的手机号，是不是 其他骑手的手机号
            DeliveryRiderBriefInfo otherDeliveryRider = riderMapper.queryRiderInfoByPhone(phone);
            if (otherDeliveryRider != null) {
                log.error("requestId {}, 已有重复的骑手信息，{}",requestId, JSONObject.toJSONString(deliveryRider));
                return ResultGenerator.genFailResult(ResultCode.INTERNAL_SERVER_ERROR, "已有骑手使用该手机号，不能使用重复的手机号，请更新为其他手机号，骑手: "+ otherDeliveryRider.getName() +" 所属租户: " + otherDeliveryRider.getTenantName());
            }
        }

        int updatedCount = riderMapper.update(new LambdaUpdateWrapper<DeliveryRider>()
                .set(DeliveryRider::getName, name)
                .set(DeliveryRider::getPhone, phone)
                .set(DeliveryRider::getPassword, password)
                .set(DeliveryRider::getStatus, status)
                .set(DeliveryRider::getType, type)
                .set(DeliveryRider::getUpdateTime, LocalDateTime.now())
                .eq(DeliveryRider::getId, riderId)
                .eq(DeliveryRider::getDelFlag, false));
        log.info("requestId {}, /editDeliveryRiderInfo, updated count: {}", requestId, updatedCount);
        return ResultGenerator.genSuccessResult();
    }


    /**
     * 接口 2.7.4 根据骑手id删除骑手
     * @param riderId
     * @return
     */
    @DeleteMapping("/deleteDeliveryRider")
    public Result<Void> deleteDeliveryRider(@RequestParam(name = "riderId") String riderId) {
        String requestId = UUID.randomUUID().toString();
        log.info("requestId {}, /deleteDeliveryRider, riderId: {}", requestId, riderId);
        int deletedCount = riderMapper.deleteById(riderId);
        log.info("requestId {}, /deleteDeliveryRider, deleted count: {}", requestId, deletedCount);
        return ResultGenerator.genSuccessResult();
    }

    /**
     * 接口 2.7.5 修改配送员状态(启用或禁用)，骑手类型(专属或共享)
     * @param riderId 骑手id
     * @param type 骑手类型，1: 专属，2: 共享
     * @param status 骑手状态
     * @return ok
     */
    @GetMapping("/changeDeliveryRiderStatus")
    public Result<Void> changeDeliveryRiderStatus(@RequestParam(name = "riderId") String riderId,
                                                  @RequestParam(name = "type") int type,
                                                  @RequestParam(name = "status") int status) {
        String requestId = UUID.randomUUID().toString();
        log.info("requestId {}, /changeDeliveryRiderStatus, riderId: {}, type: {}, status: {}", requestId, riderId, type, status);
        int updatedCount = riderMapper.update(
                new LambdaUpdateWrapper<DeliveryRider>()
                        .set(DeliveryRider::getType, type)
                        .set(DeliveryRider::getStatus, status)
                        .set(DeliveryRider::getUpdateTime, LocalDateTime.now())
                        .eq(DeliveryRider::getId, riderId));
        log.info("requestId {}, /changeDeliveryRiderStatus, updated count: {}", requestId, updatedCount);
        return ResultGenerator.genSuccessResult();
    }


    /**
     * 接口 2.7.6 根据骑手id获取骑手详情
     * @param riderId
     * @return
     */
    @GetMapping("/queryDeliveryRiderById")
    public Result<JSONObject> queryDeliveryRiderById(@RequestParam(name = "riderId") String riderId) {
        String requestId = UUID.randomUUID().toString();
        log.info("requestId {}, /queryDeliveryRiderById, riderId: {}", requestId, riderId);
        List<DeliveryRider> deliveryRiders = riderMapper.selectList(
                new LambdaQueryWrapper<DeliveryRider>()
                        .eq(DeliveryRider::getId, riderId)
                        .eq(DeliveryRider::getDelFlag, false));

        if (!CollectionUtils.isEmpty(deliveryRiders)) {
            DeliveryRider deliveryRider = deliveryRiders.get(0);
            JSONObject riderDetailInfo = new JSONObject();
            riderDetailInfo.put("riderId", deliveryRider.getId());
            riderDetailInfo.put("name", deliveryRider.getName());
            riderDetailInfo.put("phone", deliveryRider.getPhone());
            riderDetailInfo.put("password", deliveryRider.getPassword());
            riderDetailInfo.put("status", deliveryRider.getStatus());
            riderDetailInfo.put("type", deliveryRider.getType());
            log.info("requestId {}, /queryDeliveryRiderById, find: {} riders" , requestId, deliveryRiders.size());
            return ResultGenerator.genSuccessResult(riderDetailInfo);
        } else {
            log.error("requestId {}, /queryDeliveryRiderById, can't find rider: {}", requestId, riderId);
            return ResultGenerator.genFailResult(ResultCode.INTERNAL_SERVER_ERROR, "查询的骑手不存在");
        }
    }
}
